﻿// ReSharper disable InconsistentNaming

using System;
using System.Collections.Generic;
using System.Linq;
using Common;
using ImageProcessing.Matchers;
using ImageProcessing.Descriptors;
using ImageProcessing.Detectors;
using ImageProcessing.Common;
using NUnit.Framework;

namespace ImageProcessing.Tests.Matchers
{
#if DEVMACINE
    [TestFixture]
#else
    [TestFixture, Ignore]
#endif
    public class MatcherOrderedPointsTests
    {
        // training sets
        private readonly List<InterestPoint> traingingSets = new List<InterestPoint>();
        protected readonly List<TestCaseData> TestCaseData = new List<TestCaseData>();

        private readonly List<string> squareObservedList = new List<string>() { "TestPics\\Square85.png", "TestPics\\Square65.png", "TestPics\\Square35.png" };
        private readonly List<string> sqaureTrainedList = new List<string>() { "TestPics\\Square100.png", "TestPics\\Square75.png", "TestPics\\Square50.png", "TestPics\\Square25.png" };

        private readonly List<string> usbObservedList = new List<string>();
        //private readonly List<string> usbTrainedList = new List<string>() { "TestPics\\Usb100.jpg", "TestPics\\Usb75.jpg", "TestPics\\Usb50.jpg", "TestPics\\Usb25.jpg" };
        private readonly List<string> usbTrainedList = new List<string>() { "TestPics\\Usb100.jpg" }; //, "TestPics\\Usb75.jpg", "TestPics\\Usb50.jpg", "TestPics\\Usb25.jpg" };
        private HandlerNearestNeighbour _handlerNearestNeighbour;
        private int height = 300;
        private int width = 300;

        [SetUp]
        public void Setup()
        {
            _handlerNearestNeighbour = new HandlerNearestNeighbour();
        }

        public IEnumerable<TestCaseData> TestCasesInput
        {
            get
            {
                // add square training pictures
                foreach (string sqObservedItem in squareObservedList)
                {
                    TestCaseData.Add(new TestCaseData(sqaureTrainedList, sqObservedItem));
                }

                for (int i = 1; i <= 11; i++)
                {
                    usbObservedList.Add("TestPics\\USB" + i + ".jpg");
                }

                foreach (string usbObservedItem in usbObservedList)
                {
                    TestCaseData.Add(new TestCaseData(usbTrainedList, usbObservedItem));
                }

                return TestCaseData;
            }
        }

        [TestCaseSource("TestCasesInput")]
        public void Classify_PointsFoundInOrder_Equal(List<string> trainingSet, string compareImageFileName)
        {
            TagInfo trainingSetTI = new TagInfo(Guid.NewGuid(),"ts");
            TagInfo compareSetTI = new TagInfo(Guid.NewGuid(),"compare");
            foreach (string ts in trainingSet)
            {
                traingingSets.AddRange(GetInterestPoints(ts, trainingSetTI));
            }

            _handlerNearestNeighbour.Train(traingingSets);

            List<InterestPoint> compareSet = GetInterestPoints(compareImageFileName, compareSetTI);
            var pointsFound = _handlerNearestNeighbour.Classify(compareSet).FirstOrDefault();
            Assert.IsNotNull(pointsFound.Value);
            Assert.Greater(pointsFound.Value.Count, 3);
        }

        private List<InterestPoint> GetInterestPoints(string imageName, TagInfo tagInfo)
        {
            var pd = new FastDetector(width, height);
            var interestPoints = HelperMethods.GetPoints(imageName, pd, width, height);

            SurfDescriptor.DecribeInterestPoints(interestPoints, false, false, pd.IntegralImage, tagInfo);

            return interestPoints;
        }
    }
}

